﻿#region 文件信息

/*----------------------------------------------------------------
//
// 文件名称：
// 文件功能描述：
// 设计要求：
//
// 文 件 名：    AppContext
// 创建者：      杨程
// 创建日期：	    2022/11/25 14:17:13

//----------------------------------------------------------------*/

#endregion

global using CommunityToolkit.Mvvm.ComponentModel;
global using CommunityToolkit.Mvvm.Input;
global using Microsoft.Extensions.DependencyInjection;
global using Microsoft.Extensions.DependencyInjection.Extensions;
global using Microsoft.Win32;
global using Newtonsoft.Json;
global using Newtonsoft.Json.Linq;
global using SqlSugar;
global using System;
global using System.Collections;
global using System.Collections.Generic;
global using System.Collections.Immutable;
global using System.Collections.ObjectModel;
global using System.Collections.Specialized;
global using System.ComponentModel;
global using System.ComponentModel.DataAnnotations;
global using System.ComponentModel.DataAnnotations.Schema;
global using System.Data;
global using System.Diagnostics;
global using System.Dynamic;
global using System.Globalization;
global using System.IO;
global using System.IO.Compression;
global using System.Linq;
global using System.Linq.Expressions;
global using System.Reflection;
global using System.Runtime.CompilerServices;
global using System.Runtime.Loader;
global using System.Security.Cryptography;
global using System.Text;
global using System.Text.RegularExpressions;
global using System.Threading.Tasks;
global using System.Windows.Input;
global using Vampirewal.Core.AppConfig;
global using Vampirewal.Core.Attributes;
global using Vampirewal.Core.Components;
global using Vampirewal.Core.ConfigOptions;
global using Vampirewal.Core.Interface;
global using Vampirewal.Core.Models;
global using Vampirewal.Core.Models.TreeModel;
global using Vampirewal.Core.SimpleMVVM;
global using Vampirewal.Core.WindoSetting;
global using System.Collections.Concurrent;
global using Vampirewal.Core.Extensions;
global using System.Threading;

namespace Vampirewal.Core;

/// <summary>
/// 程序上下文
/// </summary>
[DebuggerStepThrough]
public class VampirewalCoreContext : BaseSingleton<VampirewalCoreContext>
{
    private VampirewalCoreContext()
    {
        GlobalContext = new Dictionary<string, object>();
        ViewAndVMDic = new Dictionary<string, Type>();
    }

    #region [     全局上下文数据     ]

    /// <summary>
    /// 全局上下文字典
    /// </summary>
    private Dictionary<string, object> GlobalContext { get; set; }

    /// <summary>
    /// 添加上下文数据
    /// </summary>
    /// <param name="key"></param>
    /// <param name="value"></param>
    /// <returns></returns>
    public bool AddContext(string key, object value)
    {
        return GlobalContext.TryAdd(key, value);
    }

    /// <summary>
    /// 获取上下文数据
    /// </summary>
    /// <param name="Key"></param>
    /// <param name="value"></param>
    /// <returns></returns>
    public bool GetContext(string Key, out object value)
    {
        return GlobalContext.TryGetValue(Key, out value);
    }

    /// <summary>
    /// 获取上下文数据
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="Key"></param>
    /// <param name="value"></param>
    /// <returns></returns>
    public bool GetContext<T>(string Key, out T value)
    {
        if (GlobalContext.TryGetValue(Key, out object v))
        {
            value = (T)v;
            return true;
        }
        value = default;
        return false;
    }

    /// <summary>
    /// 移除上下文数据
    /// </summary>
    /// <param name="Key"></param>
    /// <returns></returns>
    public bool RemoveContext(string Key)
    {
        return GlobalContext.Remove(Key);
    }

    /// <summary>
    /// 获取上下文数据
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="key"></param>
    /// <returns></returns>
    public T GetContext<T>(string key)
    {
        if (GlobalContext.TryGetValue(key, out object value))
        {
            return (T)value;
        }

        return default;
    }

    /// <summary>
    /// 获取全部上下文
    /// </summary>
    /// <returns></returns>
    public Dictionary<string, object> GetAllContext()
    {
        return GlobalContext;
    }

    #endregion

    #region [     IoC容器     ]

    /// <summary>
    /// IOC容器
    /// </summary>
    internal IServiceProvider Services { get; private set; }

    /// <summary>
    /// 设置容器到程序上下文中
    /// </summary>
    /// <param name="serviceProvider"></param>
    public void SetService(IServiceProvider serviceProvider)
    {
        if (Services == null)
        {
            Services = serviceProvider;
        }
        else
        {
            throw new Exception("已构建了IServiceProvider，请勿重复构建!");
        }
    }

    /// <summary>
    /// 获取服务
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    public T GetService<T>()
    {
        return Services.GetService<T>();
    }

    /// <summary>
    /// 获取服务
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="type"></param>
    /// <returns></returns>
    public T GetService<T>(Type type)
    {
        return (T)Services.GetService(type);
    }

    /// <summary>
    /// 通过Key值获取服务
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="key"></param>
    /// <returns></returns>
    public T GetServiceByKey<T>(object key)
    {
        return Services.GetKeyedService<T>(key);
    }

    /// <summary>
    /// 从IOC容器中生成实例
    /// </summary>
    /// <param name="instanceType"></param>
    /// <param name="param"></param>
    /// <returns></returns>
    public object CreateInstance(Type instanceType, params object[] param)
    {
        return ActivatorUtilities.CreateInstance(Services, instanceType, param);
    }

    /// <summary>
    /// 从IOC容器中生成实例
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="param"></param>
    /// <returns></returns>
    public T CreateInstance<T>(params object[] param)
    {
        return ActivatorUtilities.CreateInstance<T>(Services, param);
    }

    #endregion

    #region [     View和ViewModel     ]

    /// <summary>
    /// 储存View和ViewModel的Token与Type字典
    /// </summary>
    private Dictionary<string, Type> ViewAndVMDic { get; set; }

    /// <summary>
    /// 添加View或ViewModel进字典
    /// </summary>
    /// <param name="key"></param>
    /// <param name="ViewOrViewModelType"></param>
    /// <returns></returns>
    internal bool AddViewAndVMDic(string key, Type ViewOrViewModelType)
    {
        return ViewAndVMDic.TryAdd(key, ViewOrViewModelType);
    }

    /// <summary>
    /// 获取View或ViewModel类型
    /// </summary>
    /// <param name="key"></param>
    /// <param name="type"></param>
    /// <returns></returns>
    internal bool GetViewOrViewModel(string key, out Type type)
    {
        return ViewAndVMDic.TryGetValue(key, out type);
    }

    /// <summary>
    /// 获取页面
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="ViewKey"></param>
    /// <returns></returns>
    /// <exception cref="Exception"></exception>
    internal T GetView<T>(string ViewKey)
    {
        if (ViewAndVMDic.TryGetValue(ViewKey, out Type view))
        {
            return GetService<T>(view);
        }

        throw new Exception("未注册该Key值的窗体！");
    }

    /// <summary>
    /// 获取ViewModel
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="ViewModelKey"></param>
    /// <returns></returns>
    /// <exception cref="Exception"></exception>
    internal T GetViewModel<T>(string ViewModelKey)
    {
        if (ViewAndVMDic.TryGetValue(ViewModelKey, out Type viewmodel))
        {
            return GetService<T>(viewmodel);
        }

        throw new Exception("未注册该key值的ViewModel！");
    }

    #endregion

    #region [     获取/保存配置     ]

    internal IVampirewalCoreAppConfig AppConfig { get; set; }

    /// <summary>
    /// 获取配置项
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    public T GetOptions<T>() where T :class, IOptions,new()
    {
        return AppConfig.LoadOption<T>();
    }

    /// <summary>
    /// 保存配置项
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="options"></param>
    public void SetOptions<T>(T options) where T : class, IOptions,new()
    {
        AppConfig.SaveOption<T>(options);
    }

    /// <summary>
    /// 完整保存配置文件
    /// </summary>
    public void SaveConfig()
    {
        AppConfig.SaveAllOption();
    }

    #endregion
}